package Game.GameElements 
{
	import Box2D.Common.Math.b2Math;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Common.ContactListener;
	import Common.Managers.SwfManager;
	import Common.Utils;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	import flash.utils.getTimer;
	import flash.utils.Timer;
	import Game.Effects.Explosion;
	import Game.Windows.DebugWindow;
	import Game.World;
	/**
	 * ...
	 * @author Yevgeniy Logachev
	 */
	public class BattleTower extends GameObject
	{
		private var 		m_tower:MovieClip;
		public  static var 	m_swfPath:String 		= Settings.pathRes + "swf/battleTower.swf";
		private static var 	m_towerType:Array 		= ["Barrel", "Barrel", "Barrel", "Barrel"];
		public static var 	m_basisType:Array 		= ["Basis", "Basis", "Basis", "Basis"];
		
		private static var 	m_rotationSpeed:int		= 3;
		private static var 	m_rotationDirection:int	= 1;
		
		private var 		m_rocket:MovieClip		= null;
		private var 		m_towerRadius:Number 	= 0;
		
		private static var 	m_targetAngle:int		= 0;
		private static var 	m_radiusVisiblity:int	= 250;
		
		private var m_timerBlinking:Timer 			= null;
		private var m_lastTimeRocket:uint			= getTimer();
		
		private var m_healthBar:Sprite				= null;
		private var m_health:int					= 100;
		private var m_stamina:int					= 12;
		
		public function BattleTower(startX:int, startY:int, startRot:int, type:int = 0, isPhysicalObject:Boolean = true, isStatic:Boolean = false) 
		{
			super(startX, startY, startRot, m_swfPath, m_basisType, type, isPhysicalObject, isStatic);
			
			isEnemy = true;
			
			World.instance.objectLayer.addChild(this);
			m_tower = SwfManager.instance.getSprite(m_swfPath, m_towerType[0]) as MovieClip;
			m_healthBar = SwfManager.instance.getSprite(m_swfPath, "HealthBar") as Sprite;//objectSprite.getChildByName("healthBar") as Sprite;
			
			gameObjects.push(this);
		}
		
		public static function deserialize(data:ByteArray):BattleTower
		{
			var startX:int = data.readInt();
			var startY:int = data.readInt();
			var startRot:int = data.readInt();
			var type:int = data.readInt();
			var isPhisical:Boolean = data.readBoolean();
			var isStatic:uint = data.readUnsignedInt();
								
			return new BattleTower(startX, startY, startRot, type, isPhisical, (isStatic > 0) ? false : true);
		}
		
		override public function serialize(data:ByteArray):void
		{
			data.writeInt(x);
			data.writeInt(y);
			data.writeInt(rotation);
			data.writeInt(m_indxObj);
			data.writeBoolean((physicalObject != null) ? true : false);
			data.writeUnsignedInt((physicalObject != null) ? physicalObject.GetType() : 0);
		}
		
		override public function update():void
		{
			super.update();
			if (isDestroyed)
			{
				new Explosion(x, y);
				World.instance.objectLayer.removeChild(this);				
				release();
			}
			
			// tower radius
			if (isLoaded(m_swfPath) && m_towerRadius == 0)
			{
				addChild(m_tower);
				addChild(m_healthBar);
				m_towerRadius = (m_tower.width > m_tower.height) ? m_tower.width * 0.8 : m_tower.height * 0.8;
			}
			else if(!isLoaded(m_swfPath))
			{
				return;
			}
			
			var isDoRocket:Boolean = false;
			
			for each(var target:GameObject in GameObject.gameObjects)
			{
				if (target is Tank && Point.distance(new Point(target.x, target.y), new Point(x, y)) < m_radiusVisiblity)
				{
					rotateTo(target.x, target.y);
					isDoRocket = true;
				}
			}
			
			if (Math.abs.apply(null, [m_targetAngle - m_tower.rotation]) > 2 * m_rotationSpeed)
			{
				m_tower.rotation += m_rotationSpeed * m_rotationDirection;
			}
			else
			{
				if(isDoRocket)	doRocket();
			}
			
			//if (m_rocket != null && m_rocket.isExposion)
			//{
				//Main.mainSprite.removeChild(m_rocket);
				//m_rocket = null;
			//}
			
			if (m_healthBar != null)
			{
				m_healthBar.rotation = -rotation;
			}
		}
		
		public function rotateTo(posX:int, posY:int):void
		{
			m_targetAngle = Math.atan2(posY - y, posX - x) * 180.0 / Math.PI - rotation;
			if (m_targetAngle > 180) m_targetAngle -= 360;
			else if (m_targetAngle < -180) m_targetAngle += 360;
			
			var rot1:Number = (m_targetAngle < 0) ? m_targetAngle + 360 : m_targetAngle;
			var rot2:Number = (m_tower.rotation < 0) ? m_tower.rotation + 360 : m_tower.rotation;
			
			m_rotationDirection = (Utils.getDirectionRotate(rot1, rot2) < 0) ? 1 : -1;
			
			//DebugWindow.instance.addLine("target angle: " + m_targetAngle + " : " + m_tower.rotation + " : " + m_rotationDirection);
		}
		
		override public function doDestroy():void
		{
			m_health -= 5;
			if (m_health <= 0)
			{
				isDestroyed = true;
				m_health = 0;
			}
			
			if (m_healthBar != null)
			{
				(m_healthBar.getChildByName("healthBar") as Sprite).scaleX = m_health / 100;
			}
			
			if (m_timerBlinking == null)
			{
				m_timerBlinking = new Timer(70, 15);
				m_timerBlinking.addEventListener(TimerEvent.TIMER, updateBlink, false, 0, true);
				m_timerBlinking.addEventListener(TimerEvent.TIMER_COMPLETE, cancelBlink, false, 0, true);
				m_timerBlinking.start();
			}
			else
			{
				m_timerBlinking.reset();
				m_timerBlinking.start();
			}
		}
		
		// Destroy effect
		private function updateBlink(e:Event):void
		{
			if (filters.length == 0)
			{
				var matrix:Array = new Array();
				matrix = matrix.concat([0.93, 0,   0,   0, 0]); // red
				matrix = matrix.concat([0,    0.1, 0,   0, 0]); // green
				matrix = matrix.concat([0,    0,   0.1, 0, 0]); // blue
				matrix = matrix.concat([0,    0,   0,   1, 0]); // alpha

				var filter:ColorMatrixFilter = new ColorMatrixFilter(matrix);  
				
				filters = [filter];
			}
			else
			{
				filters = [];
			}
		}
		
		private function cancelBlink(e:Event):void
		{
			filters = [];
			
			m_timerBlinking.removeEventListener(TimerEvent.TIMER, updateBlink);
			m_timerBlinking.removeEventListener(TimerEvent.TIMER_COMPLETE, cancelBlink);
			m_timerBlinking = null;
		}
		
		public function doRocket():void
		{
			if ((getTimer() - m_lastTimeRocket > 500))
			{
				m_lastTimeRocket = getTimer();

				var towerAngle:Number = m_tower.rotation + rotation;
				if (towerAngle > 180) towerAngle -= 360;
				else if (towerAngle < -180) towerAngle += 360;
				
				var dx:Number = Math.cos(towerAngle * (Math.PI / 180.0)) * m_towerRadius;
				var dy:Number = Math.sin(towerAngle * (Math.PI / 180.0)) * m_towerRadius;
								
				new Rocket(this.x + dx, this.y + dy, towerAngle, this);
				//Main.mainSprite.addChild(m_rocket);
			}
		}
	}

}